home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / bash / bash_108 / bash-108.zoo / bash-1.08 / execute_cmd.c.orig < prev    next >
Encoding:
Text File  |  1991-05-19  |  64.1 KB  |  2,433 lines

  1. /* execute_command.c -- Execute a COMMAND structure. */
  2.  
  3. /* Copyright (C) 1987,1991 Free Software Foundation, Inc.
  4.  
  5.    This file is part of GNU Bash, the Bourne Again SHell.
  6.  
  7.    Bash is free software; you can redistribute it and/or modify it
  8.    under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 1, or (at your option)
  10.    any later version.
  11.  
  12.    Bash is distributed in the hope that it will be useful, but WITHOUT
  13.    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  14.    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
  15.    License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with Bash; see the file COPYING.  If not, write to the Free
  19.    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  20.  
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include <sys/types.h>
  24. #ifndef SONY
  25. #include <fcntl.h>
  26. #endif
  27. #include <sys/file.h>
  28. #include "posixstat.h"
  29. #include <signal.h>
  30.  
  31. #ifndef SIGABRT
  32. #define SIGABRT SIGIOT
  33. #endif
  34.  
  35. #include <sys/param.h>
  36. #include <errno.h>
  37.  
  38. #include "shell.h"
  39. #include "y.tab.h"
  40. #include "builtins.h"
  41. #include "flags.h"
  42. #include "hash.h"
  43. #include "jobs.h"
  44.  
  45. #ifdef ALIAS
  46. #include "alias.h"
  47. #endif
  48.  
  49. #include "sysdefs.h"
  50.  
  51. int builtin_pipe_in = NO_PIPE;
  52. int builtin_pipe_out = NO_PIPE;
  53.  
  54. extern int breaking, continuing, loop_level;
  55. extern int errno;
  56. extern int interactive;
  57.  
  58. extern int getdtablesize ();
  59. extern char *strerror ();
  60.  
  61. #if defined (USG)
  62. extern int last_made_pid;
  63. #endif
  64.  
  65. extern WORD_LIST *expand_words (), *expand_word ();
  66. extern char *make_command_string ();
  67.  
  68. /* The value returned by the last synchronous command. */
  69. int last_command_exit_value = 0;
  70.  
  71. /* The list of redirections to preform which will undo the redirections
  72.    that I made in the shell. */
  73. REDIRECT *redirection_undo_list = (REDIRECT *)NULL;
  74.  
  75. #define FD_BITMAP_DEFAULT_SIZE 32
  76. /* Functions to allocate and deallocate the structures used to pass
  77.    information from the shell to its children about file descriptors
  78.    to close. */
  79. struct fd_bitmap *
  80. new_fd_bitmap (size)
  81.      long size;
  82. {
  83.   struct fd_bitmap *ret;
  84.  
  85.   ret = (struct fd_bitmap *)xmalloc (sizeof (struct fd_bitmap));
  86.  
  87.   ret->size = size;
  88.  
  89.   if (size)
  90.     {
  91.       ret->bitmap = (char *)xmalloc (size);
  92.       bzero (ret->bitmap, size);
  93.     }
  94.   else
  95.     ret->bitmap = (char *)NULL;
  96.   return (ret);
  97. }
  98.  
  99. void
  100. dispose_fd_bitmap (fdbp)
  101.      struct fd_bitmap *fdbp;
  102. {
  103.   if (fdbp->bitmap)
  104.     free (fdbp->bitmap);
  105.  
  106.   free (fdbp);
  107. }
  108.  
  109. void
  110. close_fd_bitmap (fdbp)
  111.      struct fd_bitmap *fdbp;
  112. {
  113.   register int i;
  114.  
  115.   if (fdbp)
  116.     {
  117.       for (i = 0; i < fdbp->size; i++)
  118.     if (fdbp->bitmap[i])
  119.       {
  120.         close (i);
  121.         fdbp->bitmap[i] = 0;
  122.       }
  123.     }
  124. }
  125.  
  126. /* Execute the command passed in COMMAND.  COMMAND is exactly what
  127.    read_command () places into GLOBAL_COMMAND.  See "shell.h" for the
  128.    details of the command structure.
  129.  
  130.    EXECUTION_SUCCESS or EXECUTION_FAILURE are the only possible
  131.    return values.  Executing a command with nothing in it returns
  132.    success. */
  133. execute_command (command)
  134.      COMMAND *command;
  135. {
  136.   struct fd_bitmap *fd_close_bmap;
  137.   int r;
  138.  
  139.   fd_close_bmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE);
  140.  
  141.   /* Just do the command, but not asynchronously. */
  142.   r = execute_command_internal (command, 0, NO_PIPE, NO_PIPE, fd_close_bmap);
  143.   dispose_fd_bitmap (fd_close_bmap);
  144.   return r;
  145. }
  146.  
  147. /* Returns 1 if TYPE is a shell control structure type. */
  148. int
  149. shell_control_structure (type)
  150.      enum command_type type;
  151. {
  152.   switch (type)
  153.     {
  154.     case cm_for:
  155.     case cm_case:
  156.     case cm_while:
  157.     case cm_until:
  158.     case cm_if:
  159.     case cm_group:
  160.       return (1);
  161.  
  162.     default:
  163.       return (0);
  164.     }
  165. }
  166.  
  167. /* A function to use to unwind_protect the redirection undo list
  168.    for loops. */
  169. cleanup_redirects (list)
  170.      REDIRECT *list;
  171. {
  172.   do_redirections (list, 1, 0, 0);
  173.   dispose_redirects (list);
  174. }
  175.  
  176. /* Function to unwind_protect the redirections for functions and builtins. */
  177. cleanup_func_redirects (list)
  178.      REDIRECT *list;
  179. {
  180.   do_redirections (list, 1, 0, 0);
  181. }
  182.  
  183. restore_e_flag (value)
  184.      int value;
  185. {
  186.   exit_immediately_on_error = value;
  187. }
  188.  
  189. open_files ()
  190. {
  191.   register int i;
  192.   int f, fd_table_size;
  193.  
  194.   fd_table_size = getdtablesize ();
  195.  
  196.   fprintf (stderr, "pid %d open files:", getpid ());
  197.   for (i = 3; i < fd_table_size; i++)
  198.     {
  199.       if ((f = fcntl (i, F_GETFD, 0)) != -1)
  200.     fprintf (stderr, " %d (%s)", i, f ? "close" : "open");
  201.     }
  202.   fprintf (stderr, "\n");
  203. }
  204.  
  205. execute_command_internal (command,
  206.               asynchronous,
  207.               pipe_in, pipe_out,
  208.               fds_to_close)
  209.      COMMAND *command;
  210.      int asynchronous;
  211.      int pipe_in, pipe_out;
  212.      struct fd_bitmap *fds_to_close;
  213. {
  214.   int exec_result = EXECUTION_SUCCESS;
  215.   REDIRECT *my_undo_list = (REDIRECT *)NULL;
  216.   int invert, old_error_exit;
  217.  
  218.   if (!command || breaking || continuing)
  219.     return (EXECUTION_SUCCESS);
  220.  
  221.   run_pending_traps ();        /* XXX */
  222.  
  223.   invert = command->invert_pipeline;
  224.  
  225.   /* If a command was being explicitly run in a subshell, or if it is
  226.      a shell control-structure, and it has a pipe, then we do the command
  227.      in a subshell. */
  228.  
  229.   if (command->subshell ||
  230.       (shell_control_structure (command->type) &&
  231.        (pipe_out != NO_PIPE || pipe_in != NO_PIPE || asynchronous)))
  232.     {
  233.       int paren_pid;
  234.  
  235.       /* Fork a subshell, turn off the subshell bit, turn off job
  236.      control and call execute_command () on the command again. */
  237.       paren_pid = make_child (savestring (make_command_string (command)),
  238.                   asynchronous);
  239.       if (paren_pid == 0)
  240.     {
  241.       extern int interactive, login_shell;
  242.       int user_subshell, return_code;
  243.  
  244.       user_subshell = (command->subshell == WANT_SUBSHELL);
  245.       command->subshell = 0;
  246.  
  247.       /* If a command is asynchronous in a subshell (like ( foo ) & or
  248.          the special case of an asynchronous GROUP command where the
  249.          the subshell bit is turned on down in case cm_group: below), 
  250.          turn off `asynchronous', so that two subshells aren't spawned.
  251.  
  252.          This seems semantically correct to me.  For example, 
  253.          ( foo ) & seems to say ``do the command `foo' in a subshell
  254.          environment, but don't wait for that subshell to finish'',
  255.          and "{ foo ; bar } &" seems to me to be like functions or
  256.          builtins in the background, which executed in a subshell
  257.          environment.  I just don't see the need to fork two subshells. */
  258.  
  259.       /* Don't fork again, we are already in a subshell. */
  260.       asynchronous = 0;
  261.  
  262.       /* Subshells are neither login nor interactive. */
  263.       login_shell = interactive = 0;
  264.  
  265. #if defined (JOB_CONTROL)
  266.       /* Delete all traces that there were any jobs running.  This is
  267.          only for subshells. */
  268.       without_job_control ();
  269. #endif /* JOB_CONTROL */
  270.       do_piping (pipe_in, pipe_out);
  271.  
  272.       if (fds_to_close)
  273.         close_fd_bitmap (fds_to_close);
  274.  
  275.       if (command->redirects)
  276.         if (!(do_redirections (command->redirects, 1, 0, 0) == 0))
  277.           exit (EXECUTION_FAILURE);
  278.  
  279.       return_code =
  280.         execute_command_internal
  281.           (command, asynchronous, NO_PIPE, NO_PIPE, fds_to_close);
  282.  
  283.       /* If we were explicitly placed in a subshell with (), we need
  284.          to do the `shell cleanup' things, such as running traps[0]. */
  285.       if (user_subshell)
  286.         run_exit_trap ();
  287.  
  288.       exit (return_code);
  289.     }
  290.       else
  291.     {
  292.       close_pipes (pipe_in, pipe_out);
  293.  
  294.       /* If we are part of a pipeline, and not the end of the pipeline,
  295.          then we should simply return and let the last command in the
  296.          pipe be waited for.  If we are not in a pipeline, or are the
  297.          last command in the pipeline, then we wait for the subshell 
  298.          and return its exit status as usual. */
  299.       if (pipe_out != NO_PIPE)
  300.         return (EXECUTION_SUCCESS);
  301.  
  302.       stop_pipeline (asynchronous, (COMMAND *)NULL);
  303.  
  304.       if (!asynchronous)
  305.         {
  306.           last_command_exit_value = wait_for (paren_pid);
  307.  
  308.           /* If we have to, invert the return value. */
  309.           if (invert)
  310.         {
  311.           if (last_command_exit_value == EXECUTION_SUCCESS)
  312.             return (EXECUTION_FAILURE);
  313.           else
  314.             return (EXECUTION_SUCCESS);
  315.         }
  316.           else
  317.         return (last_command_exit_value);
  318.         }
  319.       else
  320.         {
  321.           extern int interactive;
  322.           if (interactive)
  323.         describe_pid (paren_pid);
  324.  
  325.           run_pending_traps ();        /* XXX */
  326.  
  327.           return (EXECUTION_SUCCESS);
  328.         }
  329.     }
  330.     }
  331.  
  332.   /* Handle WHILE FOR CASE etc. with redirections.  (Also '&' input
  333.      redirection.)  */
  334.   do_redirections (command->redirects, 1, 1, 0);
  335.   my_undo_list = (REDIRECT *)copy_redirects (redirection_undo_list);
  336.  
  337.   begin_unwind_frame ("loop_redirections");
  338.  
  339.   if (my_undo_list)
  340.     add_unwind_protect (cleanup_redirects, my_undo_list);
  341.  
  342.   old_error_exit = exit_immediately_on_error;
  343.   add_unwind_protect (restore_e_flag, old_error_exit);
  344.  
  345.   switch (command->type)
  346.     {
  347.     case cm_for:
  348.       exec_result = execute_for_command (command->value.For);
  349.       break;
  350.  
  351.     case cm_case:
  352.       exec_result = execute_case_command (command->value.Case);
  353.       break;
  354.  
  355.     case cm_while:
  356.       exec_result = execute_while_command (command->value.While);
  357.       break;
  358.  
  359.     case cm_until:
  360.       exec_result = execute_until_command (command->value.While);
  361.       break;
  362.  
  363.     case cm_if:
  364.       exec_result = execute_if_command (command->value.If);
  365.       break;
  366.  
  367.     case cm_group:
  368.  
  369.       /* This code can be executed from either of two paths: an explicit
  370.      '{}' command, or via a function call.  If we are executed via a
  371.      function call, we have already taken care of the function being
  372.      executed in the background (down there in execute_simple_command ()),
  373.      and this command should *not* be marked as asynchronous.  If we
  374.      are executing a regular '{}' group command, and asynchronous == 1,
  375.      we must want to execute the whole command in the background, so we
  376.      need a subshell, and we want the stuff executed in that subshell
  377.      (this group command) to be executed in the foreground of that
  378.      subshell (i.e. there will not be *another* subshell forked).
  379.  
  380.      What we do is to force a subshell if asynchronous, and then call
  381.      execute_command_internal again with asynchronous still set to 1,
  382.      but with the original group command, so the printed command will
  383.      look right.
  384.  
  385.      The code above that handles forking off subshells will note that
  386.      both subshell and async are on, and turn off async in the child
  387.      after forking the subshell (but leave async set in the parent, so
  388.      the normal call to describe_pid is made).  This turning off
  389.      async is *crucial*; if it is not done, this will fall into an
  390.      infinite loop of executions through this spot in subshell after
  391.      subshell until the process limit is exhausted. */
  392.  
  393.       if (asynchronous)
  394.     {
  395.       command->subshell = FORCE_SUBSHELL;
  396.       exec_result =
  397.         execute_command_internal (command, 1, pipe_in, pipe_out,
  398.                       fds_to_close);
  399.     }
  400.       else
  401.     {
  402.       exec_result =
  403.         execute_command_internal (command->value.Group->command,
  404.                       asynchronous, pipe_in, pipe_out,
  405.                       fds_to_close);
  406.     }
  407.       break;
  408.  
  409.     case cm_simple:
  410.       {
  411.     pid_t last_pid = last_made_pid;
  412.     
  413. #if defined (JOB_CONTROL)
  414.     extern int already_making_children;
  415. #endif /* JOB_CONTROL */
  416.     exec_result =
  417.       execute_simple_command (command->value.Simple, pipe_in, pipe_out,
  418.                   asynchronous, fds_to_close);
  419.  
  420.     /* The temporary environment should be used for only the simple
  421.        command immediately following its definition. */
  422.     dispose_used_env_vars ();
  423.  
  424.     /* If we forked to do the command, then we must
  425.        wait_for() the child. */
  426. #if defined (JOB_CONTROL)
  427.     if (already_making_children && pipe_out == NO_PIPE)
  428. #else
  429.       if (pipe_out == NO_PIPE)
  430. #endif /* JOB_CONTROL */
  431.         {
  432.           if (last_pid != last_made_pid)
  433.         {
  434.           stop_pipeline (asynchronous, (COMMAND *)NULL);
  435.  
  436.           if (asynchronous)
  437.             {
  438.               extern int interactive;
  439.  
  440.               if (interactive)
  441.             describe_pid (last_made_pid);
  442.             }
  443.           else
  444. #if !defined (JOB_CONTROL)
  445.             /* Do not wait for asyncronous processes started from
  446.                startup files. */
  447.             if (last_made_pid != last_asynchronous_pid)
  448. #endif
  449.               /* When executing a shell function that executes other
  450.              commands, this causes the last simple command in
  451.              the function to waited for twice. */
  452.               exec_result = wait_for (last_made_pid);
  453.         }
  454.         }
  455.       }
  456.       if (exit_immediately_on_error && !invert &&
  457.       (exec_result != EXECUTION_SUCCESS))
  458.     {
  459.       last_command_exit_value = exec_result;
  460.       longjmp (top_level, EXITPROG);
  461.     }
  462.  
  463.       break;
  464.  
  465.     case cm_connection:
  466.       switch (command->value.Connection->connector)
  467.     {
  468.       /* Do the first command asynchronously. */
  469.     case '&':
  470.       {
  471.         COMMAND *tc = command->value.Connection->first;
  472. #ifndef JOB_CONTROL
  473.         {
  474.           REDIRECT *tr = 
  475.         make_redirection (0, r_inputa_direction,
  476.                   make_word ("/dev/null"));
  477.           tr->next = tc->redirects;
  478.           tc->redirects = tr;
  479.         }
  480. #endif                /* !JOB_CONTROL */
  481.         exec_result = execute_command_internal (tc, 1, pipe_in, pipe_out,
  482.                             fds_to_close);
  483.         if (command->value.Connection->second)
  484.           exec_result =
  485.         execute_command_internal (command->value.Connection->second,
  486.                       asynchronous, pipe_in, pipe_out,
  487.                       fds_to_close);
  488.       }
  489.       break;
  490.  
  491.     case ';':
  492.       /* Just call execute command on both of them. */
  493.       execute_command (command->value.Connection->first); /* XXX might need fd to close here... */
  494.       exec_result =
  495.         execute_command_internal (command->value.Connection->second,
  496.                       asynchronous, pipe_in, pipe_out,
  497.                       fds_to_close);
  498.       break;
  499.  
  500.     case '|':
  501.       {
  502.         /* Make a pipeline between the two commands. */
  503.         int fildes[2];
  504.         if (pipe (fildes) < 0)
  505.           {
  506.         report_error ("pipe error: %s", strerror (errno));
  507. #if defined (JOB_CONTROL)
  508.         /* Because of the way Bash does pipes -- creating all pipe
  509.            file descriptors before starting any of the processes
  510.            involved -- this will generally find no processes to kill,
  511.            and no pipeline to dispose of.  If the Bash pipe execution
  512.            method is changed in the future, something like this will
  513.            be needed, so it stays. */
  514.         terminate_current_pipeline ();
  515.         kill_current_pipeline ();
  516. #endif
  517.         last_command_exit_value = EXECUTION_FAILURE;
  518.         /* The unwind-protects installed below will take care
  519.            of closing all of the open file descriptors. */
  520.         throw_to_top_level ();
  521.           }
  522.         else
  523.           {
  524.         /* Here is a problem: with the new file close-on-exec
  525.            code, the read end of the pipe (fildes[0]) stays open in
  526.            the first process, so that process will never get a
  527.            SIGPIPE.  There is no way to signal the first process that
  528.            it should close fildes[0] after forking, so it remains
  529.            open.  No SIGPIPE is ever sent because there is still a
  530.            file descriptor open for reading connected to the pipe.
  531.            We take care of that here.  This passes around a bitmap
  532.            of file descriptors that must be closed after making a
  533.            child process in execute_simple_command. */
  534.  
  535.         struct fd_bitmap *fd_bitmap1, *fd_bitmap2;
  536.         int newsize;
  537.  
  538.         /* We need fd_bitmap1 and fd_bitmap2 to be at least as big
  539.            as fildes[0] and fildes[1], respectively.  If fildes[0]
  540.            and fildes[1] are both less than fds_to_close->size, then
  541.            use fds_to_close->size. */
  542.  
  543.         if (fildes[0] < fds_to_close->size)
  544.           newsize = fds_to_close->size;
  545.         else
  546.           newsize = fildes[0] + 8;    /* XXX pick a number... */
  547.  
  548.         fd_bitmap1 = new_fd_bitmap (newsize);
  549.  
  550.         if (fildes[1] < fds_to_close->size)
  551.           newsize = fds_to_close->size;
  552.         else
  553.           newsize = fildes[1] + 8;    /* XXX any number... */
  554.  
  555.         fd_bitmap2 = new_fd_bitmap (newsize);
  556.  
  557.         /* Now copy the old information into the new bitmaps. */
  558.         bcopy (fds_to_close->bitmap, fd_bitmap1->bitmap,
  559.                fds_to_close->size);
  560.  
  561.         bcopy (fds_to_close->bitmap, fd_bitmap2->bitmap,
  562.                fds_to_close->size);
  563.  
  564.         /* And mark the pipe file descriptors to be closed. */
  565.         fd_bitmap1->bitmap[fildes[0]] = 1;
  566.         fd_bitmap2->bitmap[fildes[1]] = 1; 
  567.  
  568.         /* In case there are pipe or out-of-processes errors, we
  569.            want all these file descriptors to be closed when
  570.            unwind-protects are run, and the storage used for the
  571.            bitmaps freed up. */
  572.         begin_unwind_frame ("pipe-file-descriptors");
  573.         add_unwind_protect (close_fd_bitmap, fd_bitmap1);
  574.         add_unwind_protect (close_fd_bitmap, fd_bitmap2);
  575.         add_unwind_protect (dispose_fd_bitmap, fd_bitmap1);
  576.         add_unwind_protect (dispose_fd_bitmap, fd_bitmap2);
  577.         execute_command_internal (command->value.Connection->first,
  578.                       asynchronous, pipe_in, fildes[1],
  579.                       fd_bitmap1);
  580.  
  581.         exec_result =
  582.           execute_command_internal (command->value.Connection->second,
  583.                         asynchronous, fildes[0], pipe_out,
  584.                         fd_bitmap2);
  585.  
  586.         /* We cannot call close_fd_bitmap () here.  Doing so will
  587.            cause pipelines with > 2 processes to hang. */
  588.         dispose_fd_bitmap (fd_bitmap1);
  589.         dispose_fd_bitmap (fd_bitmap2);
  590.         discard_unwind_frame ("pipe-file-descriptors");
  591.           }
  592.       }
  593.       break;
  594.  
  595.     case AND_AND:
  596.       if (asynchronous)
  597.         {
  598.           /* If we have something like a && b &, run the && stuff in a
  599.          subshell.  Force a subshell and just call
  600.          execute_command_internal again.  Leave asynchronous on
  601.          so that we get a report from the parent shell about the
  602.          background job. */
  603.           command->subshell = FORCE_SUBSHELL;
  604.           exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close);
  605.           break;
  606.         }
  607.  
  608.       /* Execute the first command.  If the result of that is successful,
  609.          then execute the second command, otherwise return. */
  610.       exit_immediately_on_error = 0;
  611.       if ((exec_result = execute_command (command->value.Connection->first))
  612.           == EXECUTION_SUCCESS)
  613.         {
  614.           exit_immediately_on_error += old_error_exit;
  615.           exec_result = execute_command (command->value.Connection->second);
  616.         }
  617.       else
  618.         exit_immediately_on_error += old_error_exit;
  619.  
  620.       break;
  621.  
  622.     case OR_OR:
  623.       if (asynchronous)
  624.         {
  625.           /* If we have something like a || b &, run the || stuff in a
  626.          subshell.  Force a subshell and just call
  627.          execute_command_internal again.  Leave asynchronous on
  628.          so that we get a report from the parent shell about the
  629.          background job. */
  630.           command->subshell = FORCE_SUBSHELL;
  631.           exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close);
  632.           break;
  633.         }
  634.  
  635.       /* Execute the first command.  If the result of that is successful,
  636.          then return, otherwise execute the second command. */
  637.       exit_immediately_on_error = 0;
  638.       if ((exec_result = execute_command (command->value.Connection->first))
  639.           != EXECUTION_SUCCESS)
  640.         {
  641.           exit_immediately_on_error += old_error_exit;
  642.           exec_result =  execute_command (command->value.Connection->second);
  643.         }
  644.       else
  645.         exit_immediately_on_error += old_error_exit;
  646.       break;
  647.     
  648.     default:
  649.       programming_error ("Bad connector `%d'!",
  650.                  command->value.Connection->connector);
  651.       longjmp (top_level, DISCARD);
  652.       break;
  653.     }
  654.       break;
  655.       
  656.     case cm_function_def:
  657.       exec_result = intern_function (command->value.Function_def->name,
  658.                      command->value.Function_def->command);
  659.       break;
  660.  
  661.     default:
  662.       programming_error ("execute_command: Bad command type `%d'!",
  663.              command->type);
  664.     }
  665.  
  666.   if (my_undo_list)
  667.     {
  668.       do_redirections (my_undo_list, 1, 0, 0);
  669.       dispose_redirects (my_undo_list);
  670.     }
  671.  
  672.   discard_unwind_frame ("loop_redirections");
  673.  
  674.   /* Invert the return value if we have to */
  675.   if (invert)
  676.     {
  677.       if (exec_result == EXECUTION_SUCCESS)
  678.     exec_result = EXECUTION_FAILURE;
  679.       else
  680.     exec_result = EXECUTION_SUCCESS;
  681.     }
  682.  
  683.   last_command_exit_value = exec_result;
  684.   run_pending_traps ();            /* XXX */
  685.   return (last_command_exit_value);
  686. }
  687.  
  688. /* Execute a FOR command.  The syntax is: FOR word_desc IN word_list;
  689.    DO command; DONE */
  690. execute_for_command (for_command)
  691.      FOR_COM *for_command;
  692. {
  693.   /* I just noticed that the Bourne shell leaves word_desc bound to the
  694.      last name in word_list after the FOR statement is done.  This seems
  695.      wrong to me; I thought that the variable binding should be lexically
  696.      scoped, i.e. only would last the duration of the FOR command.  This
  697.      behaviour can be gotten by turning on the lexical_scoping switch. */
  698.  
  699.   extern int breaking, continuing;
  700.   register WORD_LIST *releaser, *list;
  701.   WORD_DESC *temp = for_command->name;
  702.   char *identifier;
  703.   SHELL_VAR *old_value;        /* Remember the old value of x. */
  704.   int retval = EXECUTION_SUCCESS;
  705.  
  706.   if (!check_identifier (temp))
  707.     return (EXECUTION_FAILURE);
  708.  
  709.   loop_level++;
  710.   identifier = temp->word;
  711.  
  712.   list = releaser = expand_words (for_command->map_list, 0);
  713.  
  714.   if (lexical_scoping)
  715.     old_value = copy_variable (find_variable (identifier));
  716.  
  717.   while (list)
  718.     {
  719.       QUIT;
  720.       bind_variable (identifier, list->word->word);
  721.       execute_command (for_command->action);
  722.       retval = last_command_exit_value;
  723.       QUIT;
  724.  
  725.       if (breaking)
  726.     {
  727.       breaking--; 
  728.       break;
  729.     }
  730.  
  731.       if (continuing)
  732.     {
  733.       continuing--;
  734.       if (continuing)
  735.         break;
  736.     }
  737.  
  738.       list = list->next;
  739.     }
  740.   dispose_words (releaser);
  741.  
  742.   loop_level--;
  743.   
  744.   if (lexical_scoping)
  745.     {
  746.       if (!old_value)
  747.     {
  748.       makunbound (identifier, shell_variables);
  749.     }
  750.       else
  751.     {
  752.       SHELL_VAR *new_value;
  753.  
  754.       new_value = bind_variable (identifier, value_cell(old_value));
  755.       new_value->attributes = old_value->attributes;
  756.     }
  757.       dispose_variable (old_value);
  758.     }
  759.   return (retval);
  760. }
  761.  
  762. /* Execute a CASE command.  The syntax is: CASE word_desc IN pattern_list ESAC.
  763.    The pattern_list is a linked list of pattern clauses; each clause contains
  764.    some patterns to compare word_desc against, and an associated command to
  765.    execute. */
  766. execute_case_command (case_command)
  767.      CASE_COM *case_command;
  768. {
  769.   extern dispose_words ();
  770.   WORD_LIST *wlist = expand_word (case_command->word, 0);
  771.   PATTERN_LIST *clauses = case_command->clauses;
  772.   register WORD_LIST *list;
  773.   int retval = EXECUTION_SUCCESS;
  774.   char *word = (wlist) ? wlist->word->word : "";
  775.  
  776.   add_unwind_protect (dispose_words, wlist);
  777.   while (clauses)
  778.     {
  779.       QUIT;
  780.       list = clauses->patterns;
  781.       while (list)
  782.     {
  783.       WORD_LIST *es = expand_word (list->word, 0);
  784.       char *pattern = (es) ? es->word->word : "";
  785.  
  786.       if (glob_match (pattern, word, 0))
  787.         {
  788.           dispose_words (es);
  789.           execute_command (clauses->action);
  790.           retval = last_command_exit_value;
  791.           goto exit_command;
  792.         }
  793.       dispose_words (es);
  794.       list = list->next;
  795.       QUIT;
  796.     }
  797.       clauses = clauses->next;
  798.     }
  799.  exit_command:
  800.   remove_unwind_protect ();
  801.   dispose_words (wlist);
  802.   return (retval);
  803. }
  804.  
  805. /* The WHILE command.  Syntax: WHILE test DO action; DONE.
  806.    Repeatedly execute action while executing test produces
  807.    EXECUTION_SUCCESS. */
  808. execute_while_command (while_command)
  809.      WHILE_COM *while_command;
  810. {
  811.   extern int breaking;
  812.   extern int continuing;
  813.   int commands_executed = 0;
  814.   int old_error_exit = exit_immediately_on_error, return_value;
  815.  
  816.   loop_level++;
  817.   while (1)
  818.     {
  819.       exit_immediately_on_error = 0;
  820.       return_value = execute_command (while_command->test);
  821.       exit_immediately_on_error += old_error_exit;
  822.       if (return_value != EXECUTION_SUCCESS)
  823.     break;
  824.       QUIT;
  825.       commands_executed = 1;
  826.       execute_command (while_command->action);
  827.       QUIT;
  828.  
  829.       if (breaking)
  830.     {
  831.       breaking--;
  832.       break;
  833.     }
  834.  
  835.       if (continuing)
  836.     {
  837.       continuing--;
  838.       if (continuing)
  839.         break;
  840.     }
  841.       exit_immediately_on_error = 0;
  842.     }
  843.   loop_level--;
  844.   return ((commands_executed == 1) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
  845. }
  846.  
  847. /* UNTIL is just like WHILE except that the test result is negated. */
  848. execute_until_command (while_command)
  849.      WHILE_COM *while_command;
  850. {
  851.   extern int breaking;
  852.   extern int continuing;
  853.   int commands_executed = 0;
  854.   int old_error_exit = exit_immediately_on_error, return_value;
  855.  
  856.   loop_level++;
  857.   while (1)
  858.     {
  859.       exit_immediately_on_error = 0;
  860.       return_value = execute_command (while_command->test);
  861.       exit_immediately_on_error += old_error_exit;
  862.       if (return_value == EXECUTION_SUCCESS)
  863.     break;
  864.       QUIT;
  865.       commands_executed = 1;
  866.       execute_command (while_command->action);
  867.       QUIT;
  868.  
  869.       if (breaking)
  870.     {
  871.       breaking--;
  872.       break;
  873.     }
  874.  
  875.       if (continuing)
  876.     {
  877.       continuing--;
  878.       if (continuing)
  879.         break;
  880.     }
  881.     }
  882.   loop_level--;
  883.   return (commands_executed);
  884. }
  885.  
  886. /* IF test THEN command [ELSE command].
  887.    IF also allows ELIF in the place of ELSE IF, but
  888.    the parser makes *that* stupidity transparent. */
  889. execute_if_command (if_command)
  890.      IF_COM *if_command;
  891. {
  892.   int old_error_exit = exit_immediately_on_error, return_value;
  893.  
  894.   exit_immediately_on_error = 0;
  895.   return_value = execute_command (if_command->test);
  896.   exit_immediately_on_error += old_error_exit;
  897.  
  898.   if (return_value == EXECUTION_SUCCESS)
  899.     {
  900.       QUIT;
  901.       return (execute_command (if_command->true_case));
  902.     }
  903.   else
  904.     {
  905.       QUIT;
  906.       return (execute_command (if_command->false_case));
  907.     }
  908. }
  909.  
  910. Function *
  911. find_shell_builtin (string)
  912.      char *string;
  913. {
  914.   int i = 0;
  915.   while (shell_builtins[i].name)
  916.     {
  917.       if (shell_builtins[i].enabled &&
  918.       (STREQ (shell_builtins[i].name, string)))
  919.     return (shell_builtins[i].function);
  920.       i++;
  921.     }
  922.   return ((Function *)NULL);
  923. }
  924.  
  925. #ifdef NOTYET
  926. /*
  927.  * restore fd to the standard input
  928.  */
  929. static int
  930. restore_stdin (fd)
  931.      int fd;
  932. {
  933.   if (dup2 (fd, 0) < 0)
  934.     perror("restore_stdin: dup2:");
  935.   close (fd);
  936.   return (0);
  937. }
  938. #endif /* NOTYET */
  939.  
  940. /* The name of the command that is currently being executed.
  941.    `test' needs this, for example. */
  942. char *this_command_name;
  943. /* The last argument to the previous command, used for $_ */
  944. char *lastarg = (char *)NULL;
  945.  
  946. bind_lastarg (arg)
  947.      char *arg;
  948. {
  949.   SHELL_VAR *var;
  950.  
  951.   if (!arg)
  952.     arg = "";
  953.   var = bind_variable ("_", arg);
  954.   var->attributes &= ~att_exported;
  955. }
  956.  
  957. /* For catching RETURN in a function. */
  958. int return_catch_flag = 0;
  959. int return_catch_value;
  960. jmp_buf return_catch;
  961.  
  962. /* The meaty part of all the executions.  We have to start hacking the
  963.    real execution of commands here.  Fork a process, set things up,
  964.    execute the command. */
  965. execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
  966.      SIMPLE_COM *simple_command;
  967.      int pipe_in, pipe_out;
  968.      struct fd_bitmap *fds_to_close;
  969. {
  970.   WORD_LIST *expand_words (), *copy_word_list ();
  971.   WORD_LIST *words, *lastword;
  972.  
  973.   /* Remember what this command line looks like at invocation. */
  974.   extern int command_string_index, variable_context, line_number;
  975.   extern int ignore_function_references;
  976.   extern char *the_printed_command;
  977.   char *command_line;
  978.   int first_word_quoted;
  979.  
  980.  
  981.  
  982.   /* If we're in a function, update the pseudo-line-number information. */
  983.   if (variable_context)
  984.     line_number++;
  985.  
  986.   command_string_index = 0;
  987.   print_simple_command (simple_command);    /* expensive for scripts... */
  988.   command_line = (char *)alloca (1 + strlen (the_printed_command));
  989.   strcpy (command_line, the_printed_command);
  990.  
  991.   first_word_quoted =
  992.     (simple_command->words? simple_command->words->word->quoted : 0);
  993.  
  994.   /* If we are re-running this as the result of a command substitution, do
  995.      not expand the command words a second time. */
  996.   if (!ignore_function_references)
  997.     words = expand_words (simple_command->words);
  998.   else
  999.     words = copy_word_list (simple_command->words);
  1000.  
  1001.   /* It is possible for WORDS not to have anything left in it.
  1002.      Perhaps all the words consisted of `$foo', and there was
  1003.      no variable `$foo'. */
  1004.   if (words)
  1005.     {
  1006.       extern Function *last_shell_builtin, *this_shell_builtin;
  1007.       extern int ignore_function_references;
  1008.       Function *builtin;
  1009.       SHELL_VAR *var = find_function (words->word->word);
  1010.       char *auto_resume_value;
  1011.  
  1012.       if (echo_command_at_execute)
  1013.     {
  1014.       extern char *string_list (), *indirection_level_string ();
  1015.       char *line = string_list (words);
  1016.  
  1017.       if (line && *line)
  1018.         fprintf (stderr, "%s%s\n", indirection_level_string (), line);
  1019.  
  1020.       if (line)
  1021.         free (line);
  1022.     }
  1023.  
  1024.       if (ignore_function_references)
  1025.     var = (SHELL_VAR *)NULL;
  1026.  
  1027.       QUIT;
  1028.  
  1029.       /* 
  1030.        * Save the last word in this command, to bind to "$_" after execution.
  1031.        */
  1032.       for (lastword = words; lastword->next; lastword = lastword->next)
  1033.     ;
  1034.       lastarg = lastword->word->word;
  1035.  
  1036. #ifdef JOB_CONTROL
  1037.       /* Is this command a job control related thing? */
  1038.       if (words->word->word[0] == '%')
  1039.     {
  1040.       int r;
  1041.  
  1042.       if (async)
  1043.         {
  1044.           this_command_name = "bg";
  1045.           r = bg_builtin (words);
  1046.         }
  1047.       else
  1048.         {
  1049.           this_command_name = "fg";
  1050.           r =  fg_builtin (words);
  1051.         }
  1052.       bind_lastarg (lastarg);
  1053.       return r;
  1054.     }
  1055.  
  1056.       /* One other possiblilty.  The user may want to resume an existing job.
  1057.      If they do, find out whether this word is a candidate for a running
  1058.      job. */
  1059.       if ((auto_resume_value = get_string_value ("auto_resume")) &&
  1060.       !first_word_quoted &&
  1061.       !words->next &&
  1062.       words->word->word[0] &&
  1063.       !simple_command->redirects &&
  1064.       pipe_in == NO_PIPE &&
  1065.       pipe_out == NO_PIPE &&
  1066.       !async)
  1067.     {
  1068.       char *word = words->word->word;
  1069.       register int i, wl = strlen (word), exact;
  1070.  
  1071.       exact = strcmp (auto_resume_value, "exact") == 0;
  1072.       for (i = job_slots - 1; i > -1; i--)
  1073.         {
  1074.           if (jobs[i])
  1075.         {
  1076.           register PROCESS *p = jobs[i]->pipe;
  1077.           do
  1078.             {
  1079.               if ((JOBSTATE (i) == JSTOPPED) &&
  1080.               (strncmp (p->command, word,
  1081.                     exact ? strlen (p->command) : wl) == 0))
  1082.             {
  1083.               dispose_words (words);
  1084.               return (start_job (i, 1));
  1085.             }
  1086.               p = p->next;
  1087.             }
  1088.           while (p != jobs[i]->pipe);
  1089.         }
  1090.         }
  1091.     }
  1092. #endif
  1093.  
  1094.       /* Remember the name of this command globally. */
  1095.       this_command_name = words->word->word;
  1096.  
  1097.       /* Not a running job.  Do normal command processing. */
  1098.       maybe_make_export_env ();
  1099.       QUIT;
  1100.       run_pending_traps ();    /* XXX */
  1101.  
  1102.       /* This command could be a shell builtin or a user-defined function.
  1103.      If so, and we have pipes, then fork a subshell in here.  Else, just
  1104.      do the command. */
  1105.  
  1106.       if (var)
  1107.     builtin = (Function *)NULL;
  1108.       else
  1109.     {
  1110.       builtin = find_shell_builtin (words->word->word);
  1111.       if (builtin)
  1112.         {
  1113.           if (this_shell_builtin)
  1114.         last_shell_builtin = this_shell_builtin;
  1115.           this_shell_builtin = builtin;
  1116.         }
  1117.     }
  1118.  
  1119.       if (builtin || var)
  1120.     {
  1121.       put_command_name_into_env (this_command_name);
  1122.       if ((pipe_in != NO_PIPE) || (pipe_out != NO_PIPE) || async)
  1123.         {
  1124.           if (make_child (savestring (command_line), async) == 0)
  1125.         {
  1126. #ifdef JOB_CONTROL
  1127.           /* Eradicate all traces of job control after we fork
  1128.              the subshell, so all jobs begun by this subshell are
  1129.              in the same process group as the shell itself. */
  1130.  
  1131.           /* Allow the output of `jobs' to be piped. */
  1132.           if (builtin == jobs_builtin && !async &&
  1133.               pipe_out != NO_PIPE && pipe_in != NO_PIPE)
  1134.             kill_current_pipeline ();
  1135.           else
  1136.             without_job_control ();
  1137. #endif /* JOB_CONTROL */
  1138.  
  1139.           /* A subshell is neither a login shell nor interactive. */
  1140.           login_shell = interactive = 0;    /* XXX */
  1141.  
  1142.           do_piping (pipe_in, pipe_out);
  1143.  
  1144.           if (fds_to_close)
  1145.             close_fd_bitmap (fds_to_close);
  1146.             
  1147.           if (do_redirections (simple_command->redirects, 1, 0, 0) == 0)
  1148.             {
  1149.               if (builtin)
  1150.             {
  1151.               int result;
  1152.               extern jmp_buf top_level;
  1153.  
  1154.               /* Save the values of pipe_in and pipe_out for
  1155.                  possible later use by parse_and_execute (). */
  1156.               builtin_pipe_in = pipe_in;
  1157.               builtin_pipe_out = pipe_out;
  1158.  
  1159.               /* Give builtins a place to jump back to on failure,
  1160.                  so we don't go back up to main(). */
  1161.               if (result = setjmp (top_level))
  1162.                 exit (result);  
  1163.               exit ((*builtin) (words->next));
  1164.             }
  1165.               else
  1166.             {
  1167.               COMMAND *fc, *tc = (COMMAND *)function_cell (var);
  1168.               int result;
  1169.               extern int variable_context, line_number;
  1170.  
  1171.               remember_args (words->next, 1);
  1172.               line_number = 0;
  1173. #ifdef JOB_CONTROL
  1174.               stop_pipeline (async, (COMMAND *)NULL);
  1175. #endif
  1176.               variable_context++;
  1177.               return_catch_flag++;
  1178.  
  1179.               /* We can do this because function bodies are always
  1180.                  guaranteed to be group commands, according to the
  1181.                  grammar in parse.y.  If we don't do this now,
  1182.                  execute_command_internal will graciously fork
  1183.                  another subshell for us, and we'll lose contact
  1184.                  with the rest of the pipeline and fail to get
  1185.                  any SIGPIPE that might be sent. */
  1186.  
  1187.               if (tc->type == cm_group)
  1188.                 fc = (COMMAND *)
  1189.                   copy_command (tc->value.Group->command);
  1190.               else
  1191.                 fc = (COMMAND *)copy_command (tc);
  1192.  
  1193.               /* result = execute_command (fc); doesn't work.
  1194.                  We need to explicitly specify the pipes in
  1195.                  and out so that they are closed in all the
  1196.                  processes that rely on their being closed.  If
  1197.                  they are not, it is possible to not get the
  1198.                  SIGPIPE that we need to kill all the processes
  1199.                  sharing the pipe. */
  1200.               result = execute_command_internal
  1201.                 (fc, 0, pipe_in, pipe_out, fds_to_close);
  1202.  
  1203.               dispose_command (fc);
  1204.               variable_context--;
  1205.  
  1206.               exit (result);
  1207.             }
  1208.             }
  1209.           else
  1210.             {
  1211.               exit (EXECUTION_FAILURE);
  1212.             }
  1213.         }
  1214.           else
  1215.         {
  1216.           close_pipes (pipe_in, pipe_out);
  1217.           bind_lastarg (lastarg);
  1218.           return (EXECUTION_SUCCESS);
  1219.         }
  1220.         }
  1221.       else
  1222.         {
  1223.           int result = EXECUTION_FAILURE;
  1224.           int redir_result;
  1225.  
  1226. #if defined (RIGIDLY_POSIX_COMPLIANT)
  1227.           if (builtin && builtin == exec_builtin)
  1228.         redir_result = do_redirections (simple_command->redirects,
  1229.                         1, 1, 1);
  1230.           else
  1231. #endif /* RIGIDLY_POSIX_COMPLIANT */
  1232.         redir_result = do_redirections (simple_command->redirects,
  1233.                         1, 1, 0);
  1234.  
  1235.           if (redir_result == 0)
  1236.         {
  1237.           REDIRECT *saved_undo_list = redirection_undo_list;
  1238.  
  1239.           /* Calling the "exec" builtin changes redirections
  1240.              forever. */
  1241.           if (builtin == exec_builtin)
  1242.             {
  1243.               dispose_redirects (saved_undo_list);
  1244.               saved_undo_list = (REDIRECT *)NULL;
  1245.             }
  1246.           else
  1247.             {
  1248.               begin_unwind_frame ("saved redirects");
  1249.               add_unwind_protect (cleanup_func_redirects, (char *)saved_undo_list);
  1250.             }
  1251.  
  1252.           redirection_undo_list = (REDIRECT *)NULL;
  1253.  
  1254.           if (builtin)
  1255.             result = ((*builtin) (words->next));
  1256.           else
  1257.             {
  1258.               int return_val;
  1259.               extern int dispose_command (), pop_context ();
  1260.               jmp_buf old_return_catch;
  1261.               COMMAND *tc;
  1262.               extern int line_number;
  1263.  
  1264.               tc = (COMMAND *)copy_command (function_cell (var));
  1265.  
  1266.               push_context ();
  1267.               begin_unwind_frame ("function_calling");
  1268.               add_unwind_protect (pop_context, (char *)NULL);
  1269.               add_unwind_protect (dispose_command, (char *)tc);
  1270.  
  1271.               /* Note the second argument of "1", meaning that
  1272.              we discard the current value of "$*"!  This
  1273.              is apparently the right thing. */
  1274.               remember_args (words->next, 1);
  1275.  
  1276.               line_number = 0;
  1277.               return_catch_flag++;
  1278.               bcopy ((char *)return_catch, (char *)old_return_catch,
  1279.                  sizeof (jmp_buf));
  1280.               return_val =  setjmp (return_catch);
  1281.  
  1282.               if (return_val)
  1283.             result = return_catch_value;
  1284.               else
  1285.             result = execute_command_internal (tc, 0,
  1286.                     NO_PIPE, NO_PIPE, fds_to_close);
  1287.  
  1288.               run_unwind_frame ("function_calling");
  1289.               return_catch_flag--;
  1290.               bcopy ((char *)old_return_catch, (char *)return_catch,
  1291.                  sizeof (jmp_buf));
  1292.             }
  1293.           redirection_undo_list = saved_undo_list;
  1294.           discard_unwind_frame ("saved redirects");
  1295.         }
  1296.           do_redirections (redirection_undo_list, 1, 0, 0);
  1297.           bind_lastarg (lastarg);
  1298.           dispose_words (words);
  1299.           run_pending_traps ();    /* XXX */
  1300.           return (result);
  1301.         }
  1302.     }
  1303.  
  1304.       {
  1305.     /* Hopefully this command is defined in a disk file somewhere.
  1306.        
  1307.        1) fork ()
  1308.        2) connect pipes
  1309.        3) close file descriptors 3-NOFILE    XXX - not anymore...
  1310.        4) look up the command
  1311.        5) do redirections
  1312.        6) execve ()
  1313.        7) If the execve failed, see if the file has executable mode set.
  1314.        If so, and it isn't a directory, then execute its contents as
  1315.        a shell script.
  1316.        
  1317.        Note that the filename hashing stuff has to take place up here,
  1318.        in the parent.  This is probably why the Bourne style shells
  1319.        don't handle it, since that would require them to go through
  1320.        this gnarly hair, for no good reason.
  1321.        */
  1322.  
  1323.     char **make_word_array (), *find_user_command (),
  1324.     *find_hashed_filename ();
  1325.  
  1326.     char *hashed_file = (char *)NULL, *command, **args;
  1327.  
  1328.     /* Don't waste time trying to find hashed data for a pathname
  1329.        that is already completely specified. */
  1330.  
  1331.     if (!absolute_program (words->word->word))
  1332.       hashed_file = find_hashed_filename (words->word->word);
  1333.  
  1334.     if (hashed_file)
  1335.       command = savestring (hashed_file);
  1336.     else
  1337.       {
  1338.         /* A command containing a slash is not looked up in PATH. */
  1339.         if (absolute_program (words->word->word))
  1340.           command = savestring (words->word->word);
  1341.         else
  1342.           command = find_user_command (words->word->word);
  1343.         if (command && !hashing_disabled)
  1344.           {
  1345.         extern int dot_found_in_search;
  1346.         if (!absolute_program (words->word->word))
  1347.           remember_filename (words->word->word,
  1348.                      command, dot_found_in_search);
  1349.         /* Increase the number of hits to 1. */
  1350.         find_hashed_filename (words->word->word);
  1351.           }
  1352.       }
  1353.  
  1354.     if (command)
  1355.       put_command_name_into_env (command);
  1356.  
  1357.     /* We have to make the child before we check for the non-existance
  1358.        of COMMAND, since we want the error messages to be redirected. */
  1359.       
  1360.     if (make_child (savestring (command_line), async) == 0)
  1361.       {
  1362.         do_piping (pipe_in, pipe_out);
  1363.  
  1364.         /* Execve expects the command name to be in args[0].  So we
  1365.            leave it there, in the same format that the user used to
  1366.            type it in. */
  1367.         args = make_word_array (words);
  1368.  
  1369.         if (!command)
  1370.           {
  1371.         report_error ("%s: command not found", args[0]);
  1372.         exit (EXECUTION_FAILURE);
  1373.           }
  1374.  
  1375.         /* This functionality is now provided by close-on-exec of the
  1376.            file descriptors manipulated by redirection and piping.
  1377.            Some file descriptors still need to be closed in all children
  1378.            because of the way bash does pipes; fds_to_close is a 
  1379.            bitmap of all such file descriptors. */
  1380.         if (fds_to_close)
  1381.           close_fd_bitmap (fds_to_close);
  1382.  
  1383.         if (do_redirections (simple_command->redirects, 1, 0, 0) == 0)
  1384.           {
  1385.         signal (SIGCHLD, SIG_DFL);
  1386.         execve (command, args, export_env);
  1387.  
  1388.         /* If we get to this point, then start checking out the file.
  1389.            Maybe it is something we can hack ourselves. */
  1390.         {
  1391.           struct stat finfo;
  1392.           extern int errno;
  1393.  
  1394.           if (errno != ENOEXEC)
  1395.             {
  1396.               if ((stat (command, &finfo) == 0) &&
  1397.               (S_ISDIR (finfo.st_mode)))
  1398.             report_error ("%s: is a directory", args[0]);
  1399.               else
  1400.             file_error (command);
  1401.         
  1402.               exit (EXECUTION_FAILURE);
  1403.             }
  1404.           else
  1405.             {
  1406.               /* This file is executable.
  1407.              If it begins with #!, then help out people
  1408.              with losing operating systems.  Otherwise,
  1409.              check to see if it is a binary file by seeing
  1410.              if the first line (or up to 30 characters) are
  1411.              in the ASCII set.
  1412.              Execute the contents as shell commands. */
  1413.               extern char *shell_name;
  1414.               int larry = array_len (args) + 1;
  1415.               int i, should_exec = 0;
  1416.  
  1417.               {
  1418.             int fd = open (command, O_RDONLY);
  1419.             if (fd != -1)
  1420.               {
  1421.                 unsigned char sample[80];
  1422.                 int sample_len = read (fd, &sample[0], 80);
  1423.  
  1424.                 /* Is this supposed to be an executable script? */
  1425.                 if (strncmp (sample, "#!", 2) == 0)
  1426.                   {
  1427.                 char *execname;
  1428.                 int start;
  1429.  
  1430.                 for (i = 2;
  1431.                      whitespace (sample[i]) && i < sample_len;
  1432.                      i++);
  1433.                 start = i;
  1434.                 for (; !whitespace (sample[i]) &&
  1435.                      sample[i] != '\n' && i < sample_len;
  1436.                      i++);
  1437.  
  1438.                 execname = (char *)xmalloc (1 + (i - start));
  1439.                 strncpy (execname, sample + start, i - start);
  1440.                 execname[i - start] = '\0';
  1441.  
  1442.                 should_exec = 1;
  1443.                 shell_name = execname;
  1444.                   }
  1445. #if defined (HAVE_CSH)
  1446.                 /* If this system has Csh, then keep the old
  1447.                    BSD semantics. */
  1448.                 else if (sample_len > 0 && sample[0] == '#')
  1449.                   {
  1450.                 /* Scripts starting with a # are for Csh. */
  1451.                 shell_name = savestring ("/bin/csh");
  1452.                 should_exec = 1;
  1453.                   }
  1454. #endif /* HAVE_CSH */
  1455.                 else
  1456.                   {
  1457.                 if (sample_len != -1)
  1458.                   if (check_binary_file (sample, sample_len))
  1459.                     {
  1460.                       report_error
  1461.                     ("%s: cannot execute binary file",
  1462.                      command);
  1463.                       exit (EX_BINARY_FILE);
  1464.                     }
  1465.                   }
  1466.                 close (fd);
  1467.               }
  1468.               }
  1469. #ifdef JOB_CONTROL
  1470.               /* Forget about the way that job control was working.
  1471.              We are in a subshell. */
  1472.               without_job_control ();
  1473. #endif
  1474. #ifdef ALIAS
  1475.               /* Forget about any aliases that we knew of.
  1476.              We are in a subshell. */
  1477.               delete_all_aliases ();
  1478. #endif
  1479.               /* Insert the name of this shell into the
  1480.              argument list. */
  1481.               args =
  1482.             (char **)xrealloc (args, (1 + larry) * sizeof (char *));
  1483.               for (i = larry - 1; i; i--)
  1484.             args[i] = args[i - 1];
  1485.  
  1486.               args[0] = shell_name;
  1487.               args[1] = command;
  1488.               args[larry] = (char *)NULL;
  1489.  
  1490.               if (args[0][0] == '-')
  1491.             args[0]++;
  1492.  
  1493.               if (should_exec)
  1494.             {
  1495.               struct stat finfo;
  1496.               extern int errno;
  1497.  
  1498.               execve (shell_name, args, export_env);
  1499.  
  1500.               /* Oh, no!  We couldn't even exec this! */
  1501.               if ((stat (shell_name, &finfo) == 0) &&
  1502.                   (S_ISDIR (finfo.st_mode)))
  1503.                 report_error ("%s: is a directory", args[0]);
  1504.               else
  1505.                 file_error (shell_name);
  1506.  
  1507.               exit (EXECUTION_FAILURE);
  1508.             }
  1509.               else
  1510.             {
  1511.               /* This doesn't seem to work on Ultrix 3.1
  1512.                  when executing scripts like this from
  1513.                  the .profile */
  1514.               extern jmp_buf subshell_top_level;
  1515.               extern int subshell_argc;
  1516.               extern char **subshell_argv;
  1517.               extern char **subshell_envp;
  1518.  
  1519.               subshell_argc = larry;
  1520.               subshell_argv = args;
  1521.               subshell_envp = export_env;
  1522.               longjmp (subshell_top_level, 1);
  1523.             }
  1524.             }
  1525.         }
  1526.           }
  1527.         else
  1528.           {
  1529.         exit (EXECUTION_FAILURE);
  1530.           }
  1531.       }
  1532.     else
  1533.       {
  1534.         /* Make sure that the pipes are closed in the parent. */
  1535.         close_pipes (pipe_in, pipe_out);
  1536.         if (command)
  1537.           free (command);
  1538.       }
  1539.       }
  1540.       dispose_words (words);
  1541.       bind_lastarg (lastarg);
  1542.       return (EXECUTION_SUCCESS);
  1543.     }
  1544.   else if (pipe_in != NO_PIPE || pipe_out != NO_PIPE || async)
  1545.     {
  1546.       /* We have a null command, but we really want a subshell to take
  1547.      care of it.  Just fork, do piping and redirections, and exit. */
  1548.       if (make_child (savestring (""), async) == 0)
  1549.     {
  1550.       do_piping (pipe_in, pipe_out);
  1551.  
  1552.       if (do_redirections (simple_command->redirects, 1, 0, 0) == 0)
  1553.         exit (EXECUTION_SUCCESS);
  1554.       else
  1555.         exit (EXECUTION_FAILURE);
  1556.     }
  1557.       else
  1558.     {
  1559.       bind_lastarg ("");
  1560.       close_pipes (pipe_in, pipe_out);
  1561.       return (EXECUTION_SUCCESS);
  1562.     }
  1563.     }
  1564.   else
  1565.     {
  1566.       /* Even if there aren't any command names, pretend to do the
  1567.      redirections that are specified.  The user expects the side
  1568.      effects to take place. */
  1569.       bind_lastarg ("");
  1570.       if (do_redirections (simple_command->redirects, 0, 0, 0) == 0)
  1571.     return (last_command_exit_value);
  1572.       else
  1573.     return (EXECUTION_FAILURE);
  1574.     }
  1575. }
  1576.  
  1577. close_all_files ()
  1578. {
  1579.   register int i, fd_table_size;
  1580.  
  1581.   fd_table_size = getdtablesize ();
  1582.  
  1583.   for (i = 3; i < fd_table_size; i++)
  1584.     close (i);
  1585. }
  1586.  
  1587. close_pipes (in, out)
  1588.      int in, out;
  1589. {
  1590.   if (in >= 0) close (in);
  1591.   if (out >= 0) close (out);
  1592. }
  1593.     
  1594.  
  1595. /* Redirect input and output to be from and to the specified pipes.
  1596.    NO_PIPE and REDIRECT_BOTH are handled correctly. */
  1597. do_piping (pipe_in, pipe_out)
  1598.      int pipe_in, pipe_out;
  1599. {
  1600.   if (pipe_in != NO_PIPE)
  1601.     {
  1602.       dup2 (pipe_in, 0);
  1603.       close (pipe_in);
  1604.     }
  1605.   if (pipe_out != NO_PIPE)
  1606.     {
  1607.       dup2 (pipe_out, 1);
  1608.       close (pipe_out);
  1609.  
  1610.       if (pipe_out == REDIRECT_BOTH)
  1611.     dup2 (1, 2);
  1612.     }
  1613. }
  1614.  
  1615. /* Defined in flags.c.  Non-zero means don't overwrite existing files. */
  1616. extern int noclobber;
  1617.  
  1618. #define AMBIGUOUS_REDIRECT -1
  1619. #define NOCLOBBER_REDIRECT -2
  1620. /* Perform the redirections on LIST.  If FOR_REAL, then actually make
  1621.    input and output file descriptors, otherwise just do whatever is
  1622.    neccessary for side effecting.  INTERNAL says to remember how to
  1623.    undo the redirections later, if non-zero.  If SET_CLEXEC is non-zero,
  1624.    file descriptors opened in do_redirection() have their close-on-exec
  1625.    flag set. */
  1626. do_redirections (list, for_real, internal, set_clexec)
  1627.      REDIRECT *list;
  1628.      int for_real, internal;
  1629. {
  1630.   register int error;
  1631.   register REDIRECT *temp = list;
  1632.  
  1633.   if (internal && redirection_undo_list)
  1634.     {
  1635.       dispose_redirects (redirection_undo_list);
  1636.       redirection_undo_list = (REDIRECT *)NULL;
  1637.     }
  1638.  
  1639.   while (temp)
  1640.     {
  1641.       extern char *strerror ();    /* in misc.c */
  1642.  
  1643.       error = do_redirection (temp, for_real, internal, set_clexec);
  1644.       if (error)
  1645.     {
  1646.       if (error == AMBIGUOUS_REDIRECT)
  1647.         report_error ("%s: Ambiguous redirect",
  1648.              temp->redirectee.filename->word);
  1649.       else if (error == NOCLOBBER_REDIRECT)
  1650.         report_error ("%s: Cannot clobber existing file",
  1651.               temp->redirectee.filename->word);
  1652.       else
  1653.         report_error ("%s: %s",
  1654.              temp->redirectee.filename->word,
  1655.              strerror(error));
  1656.       return (error);
  1657.     }
  1658.  
  1659.       temp = temp->next;
  1660.     }
  1661.   return (0);
  1662. }
  1663.  
  1664.  
  1665. /* Expand the word in WORD returning a string.  If WORD expands to
  1666.    multiple words (or no words), then return NULL. */
  1667. char *
  1668. redirection_expand (word)
  1669.      WORD_DESC *word;
  1670. {
  1671.   char *string_list (), *result;
  1672.   WORD_LIST *make_word_list (), *expand_words_no_vars ();
  1673.   WORD_LIST *tlist1, *tlist2;
  1674.  
  1675.   tlist1 = make_word_list (copy_word (word), (WORD_LIST *)NULL);
  1676.   tlist2 = expand_words_no_vars (tlist1);
  1677.   dispose_words (tlist1);
  1678.  
  1679.   if (!tlist2 || tlist2->next)
  1680.     {
  1681.       /* We expanded to no words, or to more than a single word.
  1682.      Dispose of the word list and return NULL. */
  1683.       if (tlist2)
  1684.     dispose_words (tlist2);
  1685.       return ((char *)NULL);
  1686.     }
  1687.   result = string_list (tlist2);
  1688.   dispose_words (tlist2);
  1689.   return (result);
  1690. }
  1691.  
  1692. /* Do the specific redirection requested.  Returns errno in case of error.
  1693.    If FOR_REAL is zero, then just do whatever is neccessary to produce the
  1694.    appropriate side effects.   REMEMBERING, if non-zero, says to remember
  1695.    how to undo each redirection.  If SET_CLEXEC is non-zero, then
  1696.    we set all file descriptors > 2 that we open to be close-on-exec.  */
  1697. do_redirection (redirect, for_real, remembering, set_clexec)
  1698.      REDIRECT *redirect;
  1699.      int for_real, remembering;
  1700. {
  1701.   WORD_DESC *redirectee = redirect->redirectee.filename;
  1702.   int redirector = redirect->redirector;
  1703.   char *redirectee_word = 0;
  1704.   enum r_instruction ri = redirect->instruction;
  1705.  
  1706.   int fd;
  1707.  
  1708.   switch (ri)
  1709.     {
  1710.     case r_output_direction:
  1711.     case r_appending_to:
  1712.     case r_input_direction:
  1713.     case r_inputa_direction:
  1714.     case r_err_and_out:        /* command &>filename */
  1715.     case r_input_output:
  1716.     case r_output_force:
  1717.  
  1718.       if (!(redirectee_word = redirection_expand (redirectee)))
  1719.     return (AMBIGUOUS_REDIRECT);
  1720.  
  1721.       /* If we are in noclobber mode, you are not allowed to overwrite
  1722.        existing files.  Check first. */
  1723.       if (noclobber && (ri == r_output_direction ||
  1724.               ri == r_input_output ||
  1725.               ri == r_err_and_out))
  1726.       {
  1727.     struct stat buf;
  1728.     if ((stat (redirectee_word, &buf) == 0) &&
  1729.         (S_ISREG (buf.st_mode)))
  1730.       return (NOCLOBBER_REDIRECT);
  1731.       }
  1732.  
  1733.       fd = open (redirectee_word, redirect->flags, 0666);
  1734.       free (redirectee_word);
  1735.  
  1736.       if (fd < 0 )
  1737.     return (errno);
  1738.  
  1739.       if (for_real)
  1740.     {
  1741.       if (remembering)
  1742.         /* Only setup to undo it if the thing to undo is active. */
  1743.         if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1))
  1744.           add_undo_redirect (redirector);
  1745.         else
  1746.           add_undo_close_redirect (redirector);
  1747.  
  1748.       if ((fd != redirector) && (dup2 (fd, redirector) < 0))
  1749.         return (errno);
  1750.  
  1751.       /*
  1752.        * If we're remembering, then this is the result of a while, for
  1753.        * or until loop with a loop redirection, or a function/builtin
  1754.        * executing in the parent shell with a redirection.  In the
  1755.        * function/builtin case, we want to set all file descriptors > 2
  1756.        * to be close-on-exec to duplicate the effect of the old
  1757.        * for i = 3 to NOFILE close(i) loop.  In the case of the loops,
  1758.        * both sh and ksh leave the file descriptors open across execs.
  1759.        * The Posix standard mentions only the exec builtin.
  1760.        */
  1761.       if (set_clexec && (redirector > 2))
  1762.         SET_CLOSE_ON_EXEC (redirector);
  1763.     }
  1764.       if (fd != redirector)
  1765.     close (fd);        /* don't close what we just opened! */
  1766.  
  1767.       /* If we are hacking both stdout and stderr, do the stderr
  1768.      redirection here. */
  1769.       if (redirect->instruction == r_err_and_out)
  1770.     {
  1771.       if (for_real)
  1772.         {
  1773.           if (remembering)
  1774.         add_undo_redirect (2);
  1775.           dup2 (1, 2);
  1776.         }
  1777.     }
  1778.       break;
  1779.  
  1780.     case r_reading_until:
  1781.     case r_deblank_reading_until:
  1782.       {
  1783.     /* REDIRECTEE is a pointer to a WORD_DESC containing the text of
  1784.        the new input.  Place it in a temporary file. */
  1785.     char *document = (char *)NULL;
  1786.     int document_index = 0;
  1787.  
  1788.     /* Expand the text if the word that was specified had no quoting.
  1789.        Note that the text that we expand is treated exactly as if it
  1790.        were surrounded by double-quotes.  */
  1791.     
  1792.     if (!redirectee)
  1793.       document = savestring ("");
  1794.     else
  1795.       {
  1796.         if (!redirectee->quoted)
  1797.           {
  1798.         WORD_LIST *temp_word_list =
  1799.           (WORD_LIST *)expand_string (redirectee->word,
  1800.                           Q_HERE_DOCUMENT);
  1801.  
  1802.         document = (char *)string_list (temp_word_list);
  1803.         if (!document)
  1804.           document = savestring ("");
  1805.         dispose_words (temp_word_list);
  1806.           }
  1807.         else
  1808.           {
  1809.         document = redirectee->word;
  1810.           }
  1811.         document_index = strlen (document);
  1812.  
  1813.         {
  1814.           char filename[40];
  1815.           int pid = getpid ();
  1816.  
  1817.           /* Make the filename for the temp file. */
  1818.           sprintf (filename, "/tmp/t%d-sh", pid);
  1819.     
  1820.           fd = open (filename, O_TRUNC | O_WRONLY | O_CREAT, 0666);
  1821.           if (fd < 0)
  1822.         {
  1823.           if (!redirectee->quoted)
  1824.             free (document);
  1825.           return (errno);
  1826.         }
  1827.           write (fd, document, document_index);
  1828.           close (fd);
  1829.           if (!redirectee->quoted)
  1830.         free (document);
  1831.  
  1832.           /* Make the document really temporary.  Also make it the
  1833.          input. */
  1834.           fd = open (filename, O_RDONLY, 0666);
  1835.  
  1836.           if (unlink (filename) < 0 || fd < 0)
  1837.         return (errno);
  1838.  
  1839.           if (for_real)
  1840.         {
  1841.           if (remembering)
  1842.             /* Only setup to undo it if the thing to undo is active. */
  1843.             if ((fd != redirector) &&
  1844.             (fcntl (redirector, F_GETFD, 0) != -1))
  1845.               add_undo_redirect (redirector);
  1846.             else
  1847.               add_undo_close_redirect (redirector);
  1848.  
  1849.           if (dup2 (fd, redirector) < 0)
  1850.             return (errno);
  1851.  
  1852.           SET_OPEN_ON_EXEC (redirector);
  1853.  
  1854.           if (set_clexec && (redirector > 2))
  1855.             SET_CLOSE_ON_EXEC (redirector);
  1856.         }
  1857.           close (fd);
  1858.         }
  1859.       }
  1860.       }
  1861.       break;
  1862.  
  1863.     case r_duplicating:
  1864.       if (for_real)
  1865.     {
  1866.       if (remembering)
  1867.         /* Only setup to undo it if the thing to undo is active. */
  1868.         if (((int)redirectee != redirector) &&
  1869.         (fcntl (redirector, F_GETFD, 0) != -1))
  1870.           add_undo_redirect (redirector);
  1871.         else
  1872.           add_undo_close_redirect (redirector);
  1873.  
  1874.       /* This is correct.  2>&1 means dup2 (1, 2); */
  1875.       dup2 ((int)redirectee, redirector);
  1876.  
  1877.       SET_OPEN_ON_EXEC (redirector);
  1878.  
  1879.       /* First duplicate the close-on-exec state of redirectee.  dup2
  1880.          leaves the flag unset on the new descriptor, which means it
  1881.          stays open.  Only set the close-on-exec bit for file descriptors
  1882.          greater than 2 in any case, since 0-2 should always be open
  1883.          unless closed by something like `exec 2<&-'. */
  1884.       /* if ((already_set || set_unconditionally) && (ok_to_set))
  1885.             set_it () */
  1886.  
  1887.       if (((fcntl (redirectee, F_GETFD, 0) == 1) || set_clexec) &&
  1888.            (redirector > 2))
  1889.         SET_CLOSE_ON_EXEC (redirector);
  1890.     }
  1891.       break;
  1892.  
  1893.     case r_close_this:
  1894.       if (for_real)
  1895.     {
  1896.       /* Don't undo the redirection, you dummy!  You're closing it! */
  1897.       close (redirector);
  1898.     }
  1899.       break;
  1900.     }
  1901.   return (0);
  1902. }
  1903.  
  1904. #define SHELL_FD_BASE    10
  1905.  
  1906. /* Remember the file descriptor associated with the slot FD,
  1907.    on REDIRECTION_UNDO_LIST.  Note that the list will be reversed
  1908.    before it is executed. */
  1909. add_undo_redirect (fd)
  1910.      int fd;
  1911. {
  1912.   int new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
  1913.   int clexec_flag = fcntl (fd, F_GETFD, 0);
  1914.   REDIRECT *new_redirect, *closer;
  1915.  
  1916.   if (new_fd < 0)
  1917.     {
  1918.       file_error ("redirection error");
  1919.       return (-1);
  1920.     }
  1921.   else
  1922.     {
  1923.       closer = make_redirection (new_fd, r_close_this, 0);
  1924.       new_redirect = make_redirection (fd, r_duplicating, new_fd);
  1925.       new_redirect->next = closer;
  1926.       closer->next = redirection_undo_list;
  1927.       redirection_undo_list = new_redirect;
  1928.       /*
  1929.        * File descriptors used only for saving others should always be
  1930.        * marked close-on-exec.  Unfortunately, we have to preserve the
  1931.        * close-on-exec state of the file descriptor we are saving, since
  1932.        * fcntl (F_DUPFD) sets the new file descriptor to remain open
  1933.        * across execs.  If, however, the file descriptor whose state we
  1934.        * are saving is <= 2, we can just set the close-on-exec flag,
  1935.        * because file descriptors 0-2 should always be open-on-exec,
  1936.        * and the restore above in do_redirection() will take care of it.
  1937.        */
  1938.       if (clexec_flag || fd < 3)
  1939.     SET_CLOSE_ON_EXEC (new_fd);
  1940.     }
  1941.   return (0);
  1942. }
  1943.  
  1944. /* Set up to close FD when we are finished with the current command
  1945.    and its redirections. */
  1946. add_undo_close_redirect (fd)
  1947.      int fd;
  1948. {
  1949.   REDIRECT *closer;
  1950.  
  1951.   closer = make_redirection (fd, r_close_this, 0);
  1952.   closer->next = redirection_undo_list;
  1953.   redirection_undo_list = closer;
  1954. }
  1955.  
  1956. intern_function (name, function)
  1957.      WORD_DESC *name;
  1958.      COMMAND *function;
  1959. {
  1960.   SHELL_VAR *var;
  1961.  
  1962.   if (!check_identifier (name))
  1963.     return (EXECUTION_FAILURE);
  1964.  
  1965.   var = find_function (name->word);
  1966.   if (var && readonly_p (var))
  1967.     {
  1968.       report_error ("%s: readonly function", var->name);
  1969.       return (EXECUTION_FAILURE);
  1970.     }
  1971.  
  1972.   bind_function (name->word, function);
  1973.   return (EXECUTION_SUCCESS);
  1974. }
  1975.  
  1976. /* Make sure that identifier is a valid shell identifier, i.e.
  1977.    does not contain a dollar sign, nor is quoted in any way.  Nor
  1978.    does it consist of all digits. */
  1979. check_identifier (word)
  1980.      WORD_DESC *word;
  1981. {
  1982.   if (word->dollar_present || word->quoted || all_digits (word->word))
  1983.     {
  1984.       report_error ("`%s' is not a valid identifier", word->word);
  1985.       return (0);
  1986.     }
  1987.   else
  1988.     return (1);
  1989. }
  1990.  
  1991. /* Return non-zero if all of the characters in STRING are digits. */
  1992. all_digits (string)
  1993.      char *string;
  1994. {
  1995.   while (*string)
  1996.     {
  1997.       if (!digit (*string))
  1998.     return (0);
  1999.       else
  2000.     string++;
  2001.     }
  2002.   return (1);
  2003. }
  2004.  
  2005. #define u_mode_bits(x) (((x) & 0000700) >> 6)
  2006. #define g_mode_bits(x) (((x) & 0000070) >> 3)
  2007. #define o_mode_bits(x) (((x) & 0000007) >> 0)
  2008. #define X_BIT(x) (x & 1)
  2009.  
  2010. /* Non-zero if the last call to executable_file () found
  2011.    the file, but stated that it wasn't executable. */
  2012. int file_exists_p = 0;
  2013.  
  2014. /* Return non-zero if FILE is an executable file, otherwise 0.
  2015.    Note that this function is the definition of what an
  2016.    executable file is; do not change this unless YOU know
  2017.    what an executable file is. */
  2018. executable_file (file)
  2019.      char *file;
  2020. {
  2021.   struct stat finfo;
  2022.   static int user_id = -1;
  2023.  
  2024.   /* If the file doesn't exist, or is a directory, then we are
  2025.      not interested. */
  2026.   file_exists_p = !stat (file, &finfo);
  2027.  
  2028.   if (!file_exists_p || S_ISDIR (finfo.st_mode))
  2029.     return (0);
  2030.  
  2031.   /* By definition, the only other criteria is that the file has
  2032.      an execute bit set that we can use. */
  2033.   if (user_id == -1)
  2034.     user_id = geteuid ();
  2035.  
  2036.   /* Root only requires execute permission for any of owner, group or
  2037.      others to be able to exec a file. */
  2038.   if (user_id == 0)
  2039.     {
  2040.       int bits;
  2041.  
  2042.       bits = (u_mode_bits (finfo.st_mode) |
  2043.           g_mode_bits (finfo.st_mode) |
  2044.           o_mode_bits (finfo.st_mode));
  2045.  
  2046.       return (X_BIT (bits));
  2047.     }
  2048.  
  2049.   /* If we are the owner of the file, the owner execute bit applies. */
  2050.   if (user_id == finfo.st_uid)
  2051.     return (X_BIT (u_mode_bits (finfo.st_mode)));
  2052.  
  2053.   /* If we are in the owning group, the group permissions apply. */
  2054.   if (group_member (finfo.st_gid))
  2055.     return (X_BIT (g_mode_bits (finfo.st_mode)));
  2056.  
  2057.   /* If `others' have execute permission to the file, then so do we,
  2058.      since we are also `others'. */
  2059.   return (X_BIT (o_mode_bits (finfo.st_mode)));
  2060. }
  2061.  
  2062. #if defined (HAVE_MULTIPLE_GROUPS)
  2063. /* The number of groups that this user is a member of. */
  2064. static int ngroups = 0;
  2065. static int *group_array = (int *)NULL;
  2066. static int default_group_array_size = 0;
  2067. #endif /* HAVE_MULTIPLE_GROUPS */
  2068.  
  2069. /* Return non-zero if GID is one that we have in our groups list. */
  2070. group_member (gid)
  2071.      int gid;
  2072. {
  2073. #if ! defined (HAVE_MULTIPLE_GROUPS)
  2074.   return ((gid == getgid ()) || (gid == getegid ()));
  2075. #else
  2076.   register int i;
  2077.  
  2078.   /* getgroups () returns the number of elements that it was able to
  2079.      place into the array.  We simply continue to call getgroups ()
  2080.      until the number of elements placed into the array is smaller than
  2081.      the physical size of the array. */
  2082.  
  2083.   while (ngroups == default_group_array_size)
  2084.     {
  2085.       default_group_array_size += 64;
  2086.  
  2087.       group_array = (int *)
  2088.     xrealloc (group_array,
  2089.           default_group_array_size * sizeof (int));
  2090.  
  2091.       ngroups = getgroups (default_group_array_size, group_array);
  2092.     }
  2093.  
  2094.   /* In case of error, the user loses. */
  2095.   if (ngroups < 0)
  2096.     return (0);
  2097.  
  2098.   /* Search through the list looking for GID. */
  2099.   for (i = 0; i < ngroups; i++)
  2100.     if (gid == group_array[i])
  2101.       return (1);
  2102.  
  2103.   return (0);
  2104. #endif /* HAVE_MULTIPLE_GROUPS */
  2105. }
  2106.  
  2107. /* DOT_FOUND_IN_SEARCH becomes non-zero when find_user_command ()
  2108.    encounters a `.' as the directory pathname while scanning the
  2109.    list of possible pathnames; i.e., if `.' comes before the directory
  2110.    containing the file of interest. */
  2111. int dot_found_in_search = 0;
  2112.  
  2113. /* Locate the executable file referenced by NAME, searching along
  2114.    the contents of the shell PATH variable.  Return a new string
  2115.    which is the full pathname to the file, or NULL if the file
  2116.    couldn't be found. If a file is found that isn't executable,
  2117.    and that is the only match, then return that. */
  2118. char *
  2119. find_user_command (name)
  2120.      char *name;
  2121. {
  2122.   char *find_user_command_internal ();
  2123.  
  2124.   return (find_user_command_internal (name, 1));
  2125. }
  2126.  
  2127. /* Locate the file referenced by NAME, searching along the contents
  2128.    of the shell PATH variable.  Return a new string which is the full
  2129.    pathname to the file, or NULL if the file couldn't be found. This
  2130.    returns the first file found. */
  2131. char *
  2132. find_path_file (name)
  2133.      char *name;
  2134. {
  2135.   char *find_user_command_internal ();
  2136.  
  2137.   return (find_user_command_internal (name, 0));
  2138. }
  2139.  
  2140. char *
  2141. find_user_command_internal (name, must_be_executable)
  2142.      char *name;
  2143.      int must_be_executable;
  2144. {
  2145.   char *path_list;
  2146.   char *find_user_command_in_path ();
  2147.  
  2148.   path_list = get_string_value ("PATH");
  2149.   if (!path_list) return (savestring (name));
  2150.  
  2151.   return (find_user_command_in_path (name, path_list, must_be_executable));
  2152. }
  2153.  
  2154. char *
  2155. user_command_matches (name, must_be_executable, state)
  2156.      char *name;
  2157.      int must_be_executable;
  2158.      int state;
  2159. {
  2160.   register int i;
  2161.   char *path_list;
  2162.   int  path_index;
  2163.   char *path_element;
  2164.   char *match;
  2165.   static char **match_list = NULL;
  2166.   static int match_list_size = 0;
  2167.   static int match_index = 0;
  2168.   char *extract_colon_unit ();
  2169.  
  2170.   if (!state)
  2171.     {
  2172.       /* Create the list of matches. */
  2173.       if (!match_list)
  2174.     {
  2175.       match_list =
  2176.         (char **) xmalloc ((match_list_size = 5) * sizeof(char *));
  2177.  
  2178.       for (i = 0; i < match_list_size; i++)
  2179.         match_list[i] = 0;
  2180.     }
  2181.  
  2182.       /* Clear out the old match list. */
  2183.       for (i = 0; i < match_list_size; i++)
  2184.     match_list[i] = NULL;
  2185.  
  2186.       /* We haven't found any files yet. */
  2187.       match_index = 0;
  2188.  
  2189.       path_list = get_string_value ("PATH");
  2190.       path_index = 0;
  2191.  
  2192.       while (path_element = extract_colon_unit (path_list, &path_index))
  2193.     {
  2194.       char *find_user_command_in_path ();
  2195.  
  2196.       match =
  2197.         find_user_command_in_path (name, path_element, must_be_executable);
  2198.  
  2199.       free (path_element);
  2200.  
  2201.       if (!match)
  2202.         continue;
  2203.  
  2204.       if (match_index + 1 == match_list_size)
  2205.         match_list =
  2206.           (char **)xrealloc (match_list,
  2207.                  ((match_list_size += 10) + 1) * sizeof (char *));
  2208.       match_list[match_index++] = match;
  2209.       match_list[match_index] = (char *)NULL;
  2210.     }
  2211.  
  2212.       /* We haven't returned any strings yet. */
  2213.       match_index = 0;
  2214.     }
  2215.  
  2216.   match = match_list[match_index];
  2217.  
  2218.   if (match)
  2219.     match_index++;
  2220.  
  2221.   return(match);
  2222. }
  2223.  
  2224. /* Return 1 if PATH1 and PATH2 are the same file.  This is kind of
  2225.    expensive.   If non-NULL STP1 and STP2 point to stat structures
  2226.    corresponding to PATH1 and PATH2, respectively. */
  2227. int
  2228. same_file (path1, path2, stp1, stp2)
  2229.      char *path1, *path2;
  2230.      struct stat *stp1, *stp2;
  2231. {
  2232.   struct stat st1, st2;
  2233.  
  2234.   if (stp1 == NULL)
  2235.     {
  2236.       if (stat (path1, &st1) != 0)
  2237.     return (0);
  2238.       stp1 = &st1;
  2239.     }
  2240.  
  2241.   if (stp2 == NULL)
  2242.     {
  2243.       if (stat (path2, &st2) != 0)
  2244.     return (0);
  2245.       stp2 = &st2;
  2246.     }
  2247.  
  2248.   return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino));
  2249. }
  2250.  
  2251. /* This does the dirty work for find_path_file () and
  2252.    find_user_command (). */
  2253. char *
  2254. find_user_command_in_path (name, path_list, must_be_executable)
  2255.      char *name;
  2256.      char *path_list;
  2257.      int must_be_executable;
  2258. {
  2259.   extern char *extract_colon_unit ();
  2260.   extern int file_exists_p;
  2261.   char *full_path;
  2262.   char *path;
  2263.   int path_index = 0;
  2264.   struct stat dot_stat_buf;
  2265.   int name_len = strlen (name);
  2266.  
  2267.   /* The file name which we would try to execute, except that it isn't
  2268.      possible to execute it.  This is the first file that matches the
  2269.      name that we are looking for while we are searching $PATH for a
  2270.      suitable one to execute.  If we cannot find a suitable executable
  2271.      file, then we use this one. */
  2272.   char *file_to_lose_on = (char *)NULL;
  2273.  
  2274.   /* We haven't started looking, so we certainly haven't seen
  2275.      a `.' as the directory path yet. */
  2276.   dot_found_in_search = 0;
  2277.  
  2278.   if (absolute_program (name))
  2279.     {
  2280.       full_path = (char *)xmalloc (1 + name_len);
  2281.       strcpy (full_path, name);
  2282.  
  2283.       if (executable_file (full_path) || file_exists_p)
  2284.     {
  2285.       return (full_path);
  2286.     }
  2287.       else
  2288.     {
  2289.       free (full_path);
  2290.       return ((char *)NULL);
  2291.     }
  2292.     }
  2293.  
  2294.   stat (".", &dot_stat_buf);   /* should set in get_working_directory */
  2295.  
  2296.   while (path_list && path_list[path_index])
  2297.     {
  2298.       path = extract_colon_unit (path_list, &path_index);
  2299.       if (!path || !*path)
  2300.     {
  2301.       if (path)
  2302.         free (path);
  2303.       path = savestring ("."); /* by definition. */
  2304.     }
  2305.  
  2306.       if (*path == '~')
  2307.     {
  2308.       char *tilde_expand ();
  2309.       char *t = tilde_expand (path);
  2310.       free (path);
  2311.       path = t;
  2312.     }
  2313.  
  2314.       /* Remember the location of "." in the path, in all its forms (as long as
  2315.      they begin with a `.', e.g. `./.') */
  2316.       if ((*path == '.') && same_file (".", path, &dot_stat_buf, (struct stat *)NULL))
  2317.     dot_found_in_search = 1;
  2318.  
  2319.       full_path = (char *)xmalloc (2 + strlen (path) + name_len);
  2320.       sprintf (full_path, "%s/%s", path, name);
  2321.       free (path);
  2322.  
  2323.       if (executable_file (full_path) ||
  2324.       (!must_be_executable && file_exists_p))
  2325.     {
  2326.       if (file_to_lose_on)
  2327.         free (file_to_lose_on);
  2328.       return (full_path);
  2329.     }
  2330.       else
  2331.     {
  2332.       if (file_exists_p && !file_to_lose_on)
  2333.         file_to_lose_on = full_path;
  2334.       else
  2335.         free (full_path);
  2336.     }
  2337.     }
  2338.  
  2339.   /* If we found a file with the right name, but not one that is
  2340.      executable, then return the one with the right name. */
  2341.   if (file_to_lose_on)
  2342.     return (file_to_lose_on);
  2343.   else
  2344.     return (char *)NULL;
  2345. }
  2346.  
  2347. /* Given a string containing units of information separated by colons,
  2348.    return the next one pointed to by INDEX, or NULL if there are no more.
  2349.    Advance INDEX to the character after the colon. */
  2350. char *
  2351. extract_colon_unit (string, index)
  2352.      char *string;
  2353.      int *index;
  2354. {
  2355.   int i, start;
  2356.  
  2357.   i = *index;
  2358.  
  2359.   if (!string || (i >= strlen (string)))
  2360.     return ((char *)NULL);
  2361.  
  2362.   /*
  2363.    * Each call to this routine leaves the index pointing at a colon if there
  2364.    * is more to the path.  If i is > 0, then increment past the `:'.  (If i
  2365.    * is 0, then the path has a leading colon.  If this is not done, the
  2366.    * second call to this routine will always return NULL, which will be
  2367.    * translated to  `.', even if `.' is not in the path.  Trailing colons
  2368.    * are handled OK by the `else' part of the if statement; it returns a null
  2369.    * string for the last component of a path with a trailing colon, and the
  2370.    * routines that call this will translate that to `.'.
  2371.    */
  2372.  
  2373.   if (i && string[i] == ':')
  2374.     i++;
  2375.  
  2376.   start = i;
  2377.  
  2378.   while (string[i] && string[i] != ':') i++;
  2379.  
  2380.   *index = i;
  2381.  
  2382.   if (i == start)
  2383.     {
  2384.       if (!string[i])
  2385.     return ((char *)NULL);
  2386.  
  2387.       (*index)++;
  2388.  
  2389.       return (savestring (""));
  2390.     }
  2391.   else
  2392.     {
  2393.       char *value;
  2394.  
  2395.       value = (char *)xmalloc (1 + (i - start));
  2396.       strncpy (value, &string[start], (i - start));
  2397.       value [i - start] = '\0';
  2398.  
  2399.       return (value);
  2400.     }
  2401. }
  2402.  
  2403. /* Return non-zero if the characters from SAMPLE are not all valid
  2404.    characters to be found in the first line of a shell script.  We
  2405.    check upto the first newline, or SAMPLE_LEN, whichever comes first.
  2406.    All of the characters must be printable or whitespace. */
  2407.  
  2408. #if !defined (isspace)
  2409. #define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\f')
  2410. #endif
  2411.  
  2412. #if !defined (isprint)
  2413. #define isprint(c) (isletter(c) || digit(c) || ispunct(c))
  2414. #endif
  2415.  
  2416. int
  2417. check_binary_file (sample, sample_len)
  2418.      unsigned char *sample;
  2419.      int sample_len;
  2420. {
  2421.   register int i;
  2422.  
  2423.   for (i = 0; i < sample_len; i++)
  2424.     {
  2425.       if (sample[i] == '\n')
  2426.     break;
  2427.  
  2428.       if (!isspace(sample[i]) && !isprint (sample[i]))
  2429.     return (1);
  2430.     }
  2431.   return (0);
  2432. }
  2433.